[swift-evolution] No access to list of environment variables possible from within Swift
Johannes Schriewer
hallo at dunkelstern.de
Sat May 28 11:57:59 CDT 2016
Hello,
Currently there is no list of environment variables visible from within a Swift program.
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.
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.
So if you want a child process to inherit the environment you’ll have to have a list.
Foundation does use a CoreFoundation method to get that list as seen here:
https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSTask.swift#L226 <https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSTask.swift#L226>
If you want to stay in Swift there is no access.
So how can a C program get to the environment? That’s rather simple, there are 2 ways:
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
2. Include `unistd.h` and use the exported variable `extern char **environ`
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.
There is a Bug on the bugtracker: https://bugs.swift.org/browse/SR-1636 <https://bugs.swift.org/browse/SR-1636>
And I have built a patch already in a pull-request that was shot down recently: https://github.com/apple/swift/pull/2757 <https://github.com/apple/swift/pull/2757>
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.
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.
As this patch only adds another static variable it will not affect existing Swift programs.
Thanks for reading,
Johannes Schriewer
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160528/c5fb0a6d/attachment.html>
More information about the swift-evolution
mailing list