1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

os: add is_executable, is_writable and is_readable

This commit is contained in:
r00ster 2020-01-06 09:15:06 +01:00 committed by Alexander Medvednikov
parent 126289c19b
commit 025efcb731
2 changed files with 82 additions and 13 deletions

View File

@ -505,13 +505,56 @@ pub fn unsetenv(name string) int {
}
}
const (
F_OK = 0
X_OK = 1
W_OK = 2
R_OK = 4
)
// exists returns true if `path` exists.
pub fn exists(path string) bool {
$if windows {
p := path.replace('/', '\\')
return C._waccess(p.to_wide(), 0) != -1
return C._waccess(p.to_wide(), F_OK) != -1
} $else {
return C.access(path.str, 0) != -1
return C.access(path.str, F_OK) != -1
}
}
// `is_executable` returns `true` if `path` is executable.
pub fn is_executable(path string) bool {
$if windows {
// NB: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/access-waccess?view=vs-2019
// i.e. there is no X bit there, the modes can be:
// 00 Existence only
// 02 Write-only
// 04 Read-only
// 06 Read and write
p := os.realpath( path )
return ( os.exists( p ) && p.ends_with('.exe') )
} $else {
return C.access(path.str, X_OK) != -1
}
}
// `is_writable` returns `true` if `path` is writable.
pub fn is_writable(path string) bool {
$if windows {
p := path.replace('/', '\\')
return C._waccess(p.to_wide(), W_OK) != -1
} $else {
return C.access(path.str, W_OK) != -1
}
}
// `is_readable` returns `true` if `path` is readable.
pub fn is_readable(path string) bool {
$if windows {
p := path.replace('/', '\\')
return C._waccess(p.to_wide(), R_OK) != -1
} $else {
return C.access(path.str, R_OK) != -1
}
}

View File

@ -234,6 +234,32 @@ fn test_symlink() {
os.rm('symlink2')
}
fn test_is_executable_writable_readable() {
file_name := os.tmpdir() + os.path_separator + 'rwxfile.exe'
mut f := os.create(file_name) or {
eprintln('failed to create file $file_name')
return
}
f.close()
$if !windows {
os.chmod(file_name, 0600) // mark as readable && writable, but NOT executable
assert os.is_writable(file_name)
assert os.is_readable(file_name)
assert !os.is_executable(file_name)
os.chmod(file_name, 0700) // mark as executable too
assert os.is_executable(file_name)
} $else {
assert os.is_writable(file_name)
assert os.is_readable(file_name)
assert os.is_executable(file_name)
}
// We finally delete the test file.
os.rm(file_name)
}
// this function is called by both test_aaa_setup & test_zzz_cleanup
// it ensures that os tests do not polute the filesystem with leftover
// files so that they can be run several times in a row.