<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hello,<div class=""><br class=""></div><div class="">Currently there is no list of environment variables visible from within a Swift program.</div><div class=""><br class=""></div><div class="">You can use `getenv` and `setenv` from the C Standard library to access a variable of which you know the name, but sometimes that’s not enough.</div><div class=""><br class=""></div><div class="">One simple case is when using `posix_spawn` to execute a child-process. This API needs a list of environment variables to present to the child process. Usually (meaning in C) you could work around that by inheriting the environment by using `fork` but that’s not allowed in Swift.</div><div class=""><br class=""></div><div class="">So if you want a child process to inherit the environment you’ll have to have a list.</div><div class=""><br class=""></div><div class="">Foundation does use a CoreFoundation method to get that list as seen here:</div><div class=""><a href="https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSTask.swift#L226" class="">https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSTask.swift#L226</a></div><div class=""><br class=""></div><div class="">If you want to stay in Swift there is no access.</div><div class=""><br class=""></div><div class="">So how can a C program get to the environment? That’s rather simple, there are 2 ways:</div><div class="">1. The (often ignored) third parameter to `main()` is a `char **env` which is just a list of all environment variables that ends with a `NULL` entry</div><div class="">2. Include `unistd.h` and use the exported variable `extern char **environ`</div><div class=""><br class=""></div><div class="">So what I would propose is just harnessing the third `main()` parameter and creating a new static computed property named `environment`, that is a dictionary of `[String:String]`, on the `Process` enum. There would be a bit of parsing because the environment list has the format `Key=Value` so the string would have to be split at the first equals character.</div><div class=""><br class=""></div><div class="">There is a Bug on the bugtracker: <a href="https://bugs.swift.org/browse/SR-1636" class="">https://bugs.swift.org/browse/SR-1636</a></div><div class="">And I have built a patch already in a pull-request that was shot down recently: <a href="https://github.com/apple/swift/pull/2757" class="">https://github.com/apple/swift/pull/2757</a></div><div class=""><br class=""></div><div class=""><div class="">I tried to keep as closely as possible to the implementation of `argv`/`Process.arguments` as that comes from the same source as the environment list. The patch touches `SILGen.cpp`, `GlobalObjects.cpp/h` and of course `Process.swift` and was created as small as possible.</div></div><div class=""><br class=""></div><div class="">If you compile with that patch you’ll get access to `Process.environment`, which is static (does not change when using `setenv` to change or add a variable) and just contains a dictionary with the environment, and `Process.unsafeEnvp` which is like `unsafeArgv` the original representation of the value at it’s original location.</div><div class=""><br class=""></div><div class="">As this patch only adds another static variable it will not affect existing Swift programs.</div><div class=""><br class=""></div><div class="">Thanks for reading,</div><div class="">Johannes Schriewer</div><div class=""><br class=""></div></body></html>