v / vlib / os
Raw file | 115 loc (106 sloc) | 2.72 KB | Latest commit hash 017ace6ea
1// Copyright (c) 2019-2023 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module os
5
6fn C.getenv(&char) &char
7
8// C.GetEnvironmentStringsW & C.FreeEnvironmentStringsW are defined only on windows
9fn C.GetEnvironmentStringsW() &u16
10
11fn C.FreeEnvironmentStringsW(&u16) int
12
13// `getenv` returns the value of the environment variable named by the key.
14// If there is not one found, it returns an empty string ''.
15pub fn getenv(key string) string {
16 return getenv_opt(key) or { '' }
17}
18
19// `getenv_opt` returns the value of a given environment variable.
20// Returns `none` if the environment variable does not exist.
21[manualfree]
22pub fn getenv_opt(key string) ?string {
23 unsafe {
24 $if windows {
25 kw := key.to_wide()
26 defer {
27 free(voidptr(kw))
28 }
29 s := C._wgetenv(kw)
30 if s == 0 {
31 return none
32 }
33 return string_from_wide(s)
34 } $else {
35 s := C.getenv(&char(key.str))
36 if s == nil {
37 return none
38 }
39 // Note: C.getenv *requires* that the result be copied.
40 return cstring_to_vstring(s)
41 }
42 }
43}
44
45// os.setenv sets the value of an environment variable with `name` to `value`.
46pub fn setenv(name string, value string, overwrite bool) int {
47 $if windows {
48 format := '${name}=${value}'
49 if overwrite {
50 unsafe {
51 return C._putenv(&char(format.str))
52 }
53 } else {
54 if getenv(name).len == 0 {
55 unsafe {
56 return C._putenv(&char(format.str))
57 }
58 }
59 }
60 return -1
61 } $else {
62 unsafe {
63 return C.setenv(&char(name.str), &char(value.str), overwrite)
64 }
65 }
66}
67
68// os.unsetenv clears an environment variable with `name`.
69pub fn unsetenv(name string) int {
70 $if windows {
71 format := '${name}='
72 return C._putenv(&char(format.str))
73 } $else {
74 return C.unsetenv(&char(name.str))
75 }
76}
77
78// See: https://linux.die.net/man/5/environ for unix platforms.
79// See: https://docs.microsoft.com/bg-bg/windows/win32/api/processenv/nf-processenv-getenvironmentstrings
80// os.environ returns a map of all the current environment variables
81
82pub fn environ() map[string]string {
83 mut res := map[string]string{}
84 $if windows {
85 mut estrings := C.GetEnvironmentStringsW()
86 mut eline := ''
87 for c := estrings; *c != 0; {
88 eline = unsafe { string_from_wide(c) }
89 eq_index := eline.index_u8(`=`)
90 if eq_index > 0 {
91 res[eline[0..eq_index]] = eline[eq_index + 1..]
92 }
93 unsafe {
94 c = c + eline.len + 1
95 }
96 }
97 C.FreeEnvironmentStringsW(estrings)
98 } $else {
99 start := &&char(C.environ)
100 mut i := 0
101 for {
102 x := unsafe { start[i] }
103 if x == 0 {
104 break
105 }
106 eline := unsafe { cstring_to_vstring(x) }
107 eq_index := eline.index_u8(`=`)
108 if eq_index > 0 {
109 res[eline[0..eq_index]] = eline[eq_index + 1..]
110 }
111 i++
112 }
113 }
114 return res
115}