-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
| Previous ID | SR-6968 |
| Radar | None |
| Original Reporter | [email protected] (JIRA User) |
| Type | Bug |
| Status | Resolved |
| Resolution | Done |
Environment
Swift 4.0.3
MacOS Sierra 10.12.6
Ubuntu 16.04
Additional Detail from JIRA
| Votes | 0 |
| Component/s | Foundation |
| Labels | Bug, Linux |
| Assignee | @spevans |
| Priority | Medium |
md5: 319865f696dd2175ab81093d8934b949
Issue Description:
Ran into the same bug as Youming Lin in SR-5076 where setenv() was not working during Linux tests.
This issue was condensed down to the following code:
import Foundation
let preset = ProcessInfo.processInfo.environment["test"]
setenv("test", "worked", 1)
let postset = ProcessInfo.processInfo.environment["test"]
print(preset)
print(postset)on macOS preset == nil and postset == "worked"
However on Linux they are both equal to nil.
Furthermore, you do not call ProcessInfo before you setenv then it does work
import Foundation
setenv("test", "worked", 1)
let postset = ProcessInfo.processInfo.environment["test"]
print(postset)and on both macOS and Linux postset == "worked"
Both examples will work if you use {{getenv("test") instead of ProcessInfo.processInfo.environment["test"].
}}We looked into ProcessInfo on foundation and at:
https://github.com/apple/swift-corelibs-foundation/blob/master/CoreFoundation/Base.subproj/CFUtilities.c#L1497
You can see that dispatch_once is used in __CFGetEnvironment().
This means that once you access ProcessInfo.processInfo.environment the first time it will cache the result and use that for any future accesses. This means that the environment variables updated by the setenv function are not reflected in the value returned by process info. I believe this is the cause of the difference in behaviour between Linux and macOS.
To fix:
Investigate why dispatch_once was chosen for this function
Look into threading requirements if dispatch_once is removed