1
/**
2
 * Functions for modifying environment variables.
3
 *
4
 * Copyright:   Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved
5
 * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
6
 * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/env.d, env.d)
7
 * Documentation:  https://dlang.org/phobos/dmd_env.html
8
 * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/env.d
9
 */
10

11
module dmd.env;
12

13
import core.stdc.string;
14
import core.sys.posix.stdlib;
15
import dmd.globals;
16
import dmd.root.array;
17
import dmd.root.rmem;
18
import dmd.root.string;
19

20
version (Windows)
21
    private extern (C) int putenv(const char*) nothrow;
22

23
/**
24
Construct a variable from `name` and `value` and put it in the environment while saving
25
the previous value of the environment variable into a global list so it can be restored later.
26
Params:
27
    name = the name of the variable
28
    value = the value of the variable
29
Returns:
30
    true on error, false on success
31
*/
32
bool putenvRestorable(const(char)[] name, const(char)[] value) nothrow
33
{
34 1
    saveEnvVar(name);
35 1
    const nameValue = allocNameValue(name, value);
36 1
    const result = putenv(cast(char*)nameValue.ptr);
37
    version (Windows)
38
        mem.xfree(cast(void*)nameValue.ptr);
39
    else
40
    {
41 1
        if (result)
42 0
            mem.xfree(cast(void*)nameValue.ptr);
43
    }
44 1
    return result ? true : false;
45
}
46

47
/**
48
Allocate a new variable via xmalloc that can be added to the global environment. The
49
resulting string will be null-terminated immediately after the end of the array.
50
Params:
51
    name = name of the variable
52
    value = value of the variable
53
Returns:
54
    a newly allocated variable that can be added to the global environment
55
*/
56
string allocNameValue(const(char)[] name, const(char)[] value) nothrow
57
{
58 1
    const length = name.length + 1 + value.length;
59 1
    auto str = (cast(char*)mem.xmalloc(length + 1))[0 .. length];
60 1
    str[0 .. name.length] = name[];
61 1
    str[name.length] = '=';
62 1
    str[name.length + 1 .. length] = value[];
63 1
    str.ptr[length] = '\0';
64 1
    return cast(string)str;
65
}
66

67
/// Holds the original values of environment variables when they are overwritten.
68
private __gshared string[string] envNameValues;
69

70
/// Restore the original environment.
71
void restoreEnvVars()
72
{
73 1
    foreach (var; envNameValues.values)
74
    {
75 1
        if (putenv(cast(char*)var.ptr))
76 0
            assert(0);
77
    }
78
}
79

80
/// Save the environment variable `name` if not saved already.
81
void saveEnvVar(const(char)[] name) nothrow
82
{
83 1
    if (!(name in envNameValues))
84
    {
85 1
        envNameValues[name.idup] = allocNameValue(name, name.toCStringThen!(n => getenv(n.ptr)).toDString);
86
    }
87
}

Read our documentation on viewing source code .

Loading