Fix AnnDotDot in module export
[ghc.git] / rts / win32 / GetEnv.c
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team 2011
4 *
5 * Access to the process environment variables
6 *
7 * ---------------------------------------------------------------------------*/
8
9 #include "Rts.h"
10 #include "RtsUtils.h"
11 #include "GetEnv.h"
12
13 #include <windows.h>
14
15 /* Windows does it differently, though arguably the most sanely.
16 * GetEnvironmentStrings() returns a pointer to a block of
17 * environment vars with a double null terminator:
18 * Var1=Value1\0
19 * Var2=Value2\0
20 * ...
21 * VarN=ValueN\0\0
22 * But because everyone else (ie POSIX) uses a vector of strings, we convert
23 * to that format. Fortunately this is just a matter of making an array of
24 * offsets into the environment block.
25 *
26 * Note that we have to call FreeEnvironmentStrings() at the end.
27 *
28 */
29 void getProgEnvv(int *out_envc, char **out_envv[]) {
30 int envc, i;
31 char *env;
32 char *envp;
33 char **envv;
34
35 /* For now, use the 'A'nsi not 'W'ide variant.
36 Note: corresponding Free below must use the same 'A'/'W' variant. */
37 env = GetEnvironmentStringsA();
38
39 envc = 0;
40 for (envp = env; *envp != 0; envp += strlen(envp) + 1) {
41 envc++;
42 }
43
44 envv = stgMallocBytes(sizeof(char*) * (envc+1), "getProgEnvv");
45
46 i = 0;
47 for (envp = env; *envp != 0; envp += strlen(envp) + 1) {
48 envv[i] = envp;
49 i++;
50 }
51 /* stash whole env in last+1 entry */
52 envv[envc] = env;
53
54 *out_envc = envc;
55 *out_envv = envv;
56 }
57
58 void freeProgEnvv(int envc, char *envv[]) {
59 /* we stashed the win32 env block in the last+1 entry */
60 FreeEnvironmentStringsA(envv[envc]);
61 stgFree(envv);
62 }