v/vlib/os/environment.v

95 lines
2.3 KiB
V

// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
module os
fn C.getenv(charptr) &char
// C.GetEnvironmentStringsW & C.FreeEnvironmentStringsW are defined only on windows
fn C.GetEnvironmentStringsW() &u16
fn C.FreeEnvironmentStringsW(&u16) int
// `getenv` returns the value of the environment variable named by the key.
pub fn getenv(key string) string {
$if windows {
s := C._wgetenv(key.to_wide())
if s == 0 {
return ''
}
return string_from_wide(s)
} $else {
s := C.getenv(charptr(key.str))
if s == voidptr(0) {
return ''
}
// NB: C.getenv *requires* that the result be copied.
return cstring_to_vstring(byteptr(s))
}
}
// os.setenv sets the value of an environment variable with `name` to `value`.
pub fn setenv(name string, value string, overwrite bool) int {
$if windows {
format := '$name=$value'
if overwrite {
unsafe {
return C._putenv(format.str)
}
} else {
if getenv(name).len == 0 {
unsafe {
return C._putenv(format.str)
}
}
}
return -1
} $else {
unsafe {
return C.setenv(charptr(name.str), charptr(value.str), overwrite)
}
}
}
// os.unsetenv clears an environment variable with `name`.
pub fn unsetenv(name string) int {
$if windows {
format := '${name}='
return C._putenv(format.str)
} $else {
return C.unsetenv(charptr(name.str))
}
}
// See: https://linux.die.net/man/5/environ for unix platforms.
// See: https://docs.microsoft.com/bg-bg/windows/win32/api/processenv/nf-processenv-getenvironmentstrings
// os.environ returns a map of all the current environment variables
pub fn environ() map[string]string {
mut res := map[string]string
$if windows {
mut estrings := C.GetEnvironmentStringsW()
mut eline := ''
for c := estrings; *c != 0; {
eline = string_from_wide(c)
eq_index := eline.index_byte(`=`)
if eq_index > 0 {
res[eline[0..eq_index]] = eline[eq_index + 1..]
}
unsafe
{
c = c + eline.len + 1
}
}
C.FreeEnvironmentStringsW(estrings)
} $else {
e := &charptr(C.environ)
for i := 0; !isnil(unsafe {e[i]}); i++ {
eline := unsafe {cstring_to_vstring(byteptr(e[i]))}
eq_index := eline.index_byte(`=`)
if eq_index > 0 {
res[eline[0..eq_index]] = eline[eq_index + 1..]
}
}
}
return res
}