os: make executable() more robust

pull/4020/head
Delyan Angelov 2020-03-13 23:19:02 +02:00 committed by GitHub
parent c2ffd027d0
commit 19f9c18305
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 14 deletions

View File

@ -806,7 +806,7 @@ pub fn executable() string {
count := C.readlink('/proc/self/exe', result, MAX_PATH)
if count < 0 {
eprintln('os.executable() failed at reading /proc/self/exe to get exe path')
return os.args[0]
return executable_fallback()
}
return string(result)
}
@ -822,7 +822,7 @@ pub fn executable() string {
ret := proc_pidpath(pid, result, MAX_PATH)
if ret <= 0 {
eprintln('os.executable() failed at calling proc_pidpath with pid: $pid . proc_pidpath returned $ret ')
return os.args[0]
return executable_fallback()
}
return string(result)
}
@ -833,11 +833,8 @@ pub fn executable() string {
C.sysctl(mib.data, 4, result, &size, 0, 0)
return string(result)
}
$if openbsd {
// "Sadly there is no way to get the full path of the executed file in OpenBSD."
// lol
return os.args[0]
}
// "Sadly there is no way to get the full path of the executed file in OpenBSD."
$if openbsd {}
$if solaris {}
$if haiku {}
$if netbsd {
@ -845,7 +842,7 @@ pub fn executable() string {
count := C.readlink('/proc/curproc/exe', result, MAX_PATH)
if count < 0 {
eprintln('os.executable() failed at reading /proc/curproc/exe to get exe path')
return os.args[0]
return executable_fallback()
}
return string(result,count)
}
@ -854,11 +851,53 @@ pub fn executable() string {
count := C.readlink('/proc/curproc/file', result, MAX_PATH)
if count < 0 {
eprintln('os.executable() failed at reading /proc/curproc/file to get exe path')
return os.args[0]
return executable_fallback()
}
return string(result,count)
}
return os.args[0]
return executable_fallback()
}
// executable_fallback is used when there is not a more platform specific and accurate implementation
// it relies on path manipulation of os.args[0] and os.wd_at_startup, so it may not work properly in
// all cases, but it should be better, than just using os.args[0] directly.
fn executable_fallback() string {
mut exepath := os.args[0]
if !os.is_abs_path(exepath) {
if exepath.contains( os.path_separator ) {
exepath = os.join_path(os.wd_at_startup, exepath)
}else{
// no choice but to try to walk the PATH folders :-| ...
foundpath := os.find_abs_path_of_executable(exepath) or { '' }
if foundpath.len > 0 {
exepath = foundpath
}
}
}
exepath = os.realpath(exepath)
return exepath
}
// find_exe_path walks the environment PATH, just like most shell do, it returns
// the absolute path of the executable if found
pub fn find_abs_path_of_executable(exepath string) ?string {
if os.is_abs_path(exepath) {
return exepath
}
mut res := ''
env_path_delimiter := if os.user_os() == 'windows' { ';' } else { ':' }
paths := os.getenv('PATH').split(env_path_delimiter)
for p in paths {
found_abs_path := os.join_path( p, exepath )
if os.exists( found_abs_path ) && os.is_executable( found_abs_path ) {
res = found_abs_path
break
}
}
if res.len>0 {
return res
}
return error('failed to find executable')
}
[deprecated]

View File

@ -3,10 +3,7 @@
// that can be found in the LICENSE file.
module table
import (
strings
os
)
import os
pub struct Table {
// struct_fields map[string][]string