2022-01-04 12:21:08 +03:00
|
|
|
// Copyright (c) 2019-2022 Alexander Medvednikov. All rights reserved.
|
2020-03-10 16:25:16 +03:00
|
|
|
// Use of this source code is governed by an MIT license
|
|
|
|
// that can be found in the LICENSE file.
|
|
|
|
module os
|
|
|
|
|
2021-04-04 17:43:32 +03:00
|
|
|
fn C.getenv(&char) &char
|
2020-12-16 12:02:36 +03:00
|
|
|
|
2020-03-10 16:25:16 +03:00
|
|
|
// C.GetEnvironmentStringsW & C.FreeEnvironmentStringsW are defined only on windows
|
|
|
|
fn C.GetEnvironmentStringsW() &u16
|
|
|
|
|
|
|
|
fn C.FreeEnvironmentStringsW(&u16) int
|
2020-12-16 12:02:36 +03:00
|
|
|
|
2020-03-10 16:25:16 +03:00
|
|
|
// `getenv` returns the value of the environment variable named by the key.
|
2021-11-19 18:32:01 +03:00
|
|
|
// If there is not one found, it returns an empty string ''.
|
2020-03-10 16:25:16 +03:00
|
|
|
pub fn getenv(key string) string {
|
2021-11-19 18:32:01 +03:00
|
|
|
return getenv_opt(key) or { '' }
|
|
|
|
}
|
|
|
|
|
|
|
|
// `getenv_opt` returns the value of the environment variable named by the key
|
|
|
|
// If there is not one found, it returns `none`.
|
|
|
|
[manualfree]
|
|
|
|
pub fn getenv_opt(key string) ?string {
|
2021-02-14 21:31:42 +03:00
|
|
|
unsafe {
|
|
|
|
$if windows {
|
2021-11-19 18:32:01 +03:00
|
|
|
kw := key.to_wide()
|
|
|
|
defer {
|
|
|
|
free(voidptr(kw))
|
|
|
|
}
|
|
|
|
s := C._wgetenv(kw)
|
2021-02-14 21:31:42 +03:00
|
|
|
if s == 0 {
|
2021-11-19 18:32:01 +03:00
|
|
|
return none
|
2021-02-14 21:31:42 +03:00
|
|
|
}
|
|
|
|
return string_from_wide(s)
|
|
|
|
} $else {
|
2021-04-04 17:43:32 +03:00
|
|
|
s := C.getenv(&char(key.str))
|
2021-02-14 21:31:42 +03:00
|
|
|
if s == voidptr(0) {
|
2021-11-19 18:32:01 +03:00
|
|
|
return none
|
2021-02-14 21:31:42 +03:00
|
|
|
}
|
2022-03-06 20:01:22 +03:00
|
|
|
// Note: C.getenv *requires* that the result be copied.
|
2021-04-05 08:08:51 +03:00
|
|
|
return cstring_to_vstring(s)
|
2020-03-10 16:25:16 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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 {
|
2020-07-20 20:06:41 +03:00
|
|
|
unsafe {
|
2021-04-04 17:43:32 +03:00
|
|
|
return C._putenv(&char(format.str))
|
2020-07-20 20:06:41 +03:00
|
|
|
}
|
2020-10-04 20:43:28 +03:00
|
|
|
} else {
|
|
|
|
if getenv(name).len == 0 {
|
|
|
|
unsafe {
|
2021-04-04 17:43:32 +03:00
|
|
|
return C._putenv(&char(format.str))
|
2020-10-04 20:43:28 +03:00
|
|
|
}
|
|
|
|
}
|
2020-03-10 16:25:16 +03:00
|
|
|
}
|
|
|
|
return -1
|
|
|
|
} $else {
|
2020-07-20 20:06:41 +03:00
|
|
|
unsafe {
|
2021-04-04 17:43:32 +03:00
|
|
|
return C.setenv(&char(name.str), &char(value.str), overwrite)
|
2020-07-20 20:06:41 +03:00
|
|
|
}
|
2020-03-10 16:25:16 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// os.unsetenv clears an environment variable with `name`.
|
|
|
|
pub fn unsetenv(name string) int {
|
|
|
|
$if windows {
|
2020-12-16 12:02:36 +03:00
|
|
|
format := '$name='
|
2021-04-04 17:43:32 +03:00
|
|
|
return C._putenv(&char(format.str))
|
2020-03-10 16:25:16 +03:00
|
|
|
} $else {
|
2021-04-04 17:43:32 +03:00
|
|
|
return C.unsetenv(&char(name.str))
|
2020-03-10 16:25:16 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
2021-04-04 21:11:17 +03:00
|
|
|
|
2021-04-06 18:00:42 +03:00
|
|
|
fn unix_environ() &&char {
|
|
|
|
// TODO: remove this helper function, when `&&char(C.environ)` works properly
|
|
|
|
return voidptr(C.environ)
|
2021-04-04 21:11:17 +03:00
|
|
|
}
|
|
|
|
|
2020-03-10 16:25:16 +03:00
|
|
|
pub fn environ() map[string]string {
|
2020-12-16 12:02:36 +03:00
|
|
|
mut res := map[string]string{}
|
2020-03-10 16:25:16 +03:00
|
|
|
$if windows {
|
|
|
|
mut estrings := C.GetEnvironmentStringsW()
|
|
|
|
mut eline := ''
|
2020-07-03 19:10:10 +03:00
|
|
|
for c := estrings; *c != 0; {
|
2021-02-15 18:15:52 +03:00
|
|
|
eline = unsafe { string_from_wide(c) }
|
2022-04-15 14:58:56 +03:00
|
|
|
eq_index := eline.index_u8(`=`)
|
2020-03-10 16:25:16 +03:00
|
|
|
if eq_index > 0 {
|
|
|
|
res[eline[0..eq_index]] = eline[eq_index + 1..]
|
|
|
|
}
|
2020-12-16 12:02:36 +03:00
|
|
|
unsafe {
|
2020-07-03 19:10:10 +03:00
|
|
|
c = c + eline.len + 1
|
|
|
|
}
|
2020-03-10 16:25:16 +03:00
|
|
|
}
|
|
|
|
C.FreeEnvironmentStringsW(estrings)
|
|
|
|
} $else {
|
2021-04-06 18:00:42 +03:00
|
|
|
start := unix_environ()
|
|
|
|
mut i := 0
|
|
|
|
for {
|
|
|
|
x := unsafe { start[i] }
|
|
|
|
if x == 0 {
|
2021-04-04 21:11:17 +03:00
|
|
|
break
|
|
|
|
}
|
2021-04-06 18:00:42 +03:00
|
|
|
eline := unsafe { cstring_to_vstring(x) }
|
2022-04-15 14:58:56 +03:00
|
|
|
eq_index := eline.index_u8(`=`)
|
2020-03-10 16:25:16 +03:00
|
|
|
if eq_index > 0 {
|
|
|
|
res[eline[0..eq_index]] = eline[eq_index + 1..]
|
|
|
|
}
|
2021-04-06 18:00:42 +03:00
|
|
|
i++
|
2020-03-10 16:25:16 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return res
|
|
|
|
}
|