go: net: Listen fails on Windows when SYSTEMROOT environment variable is not set
Under Windows, net.Listen fails with the error message socket: The requested service provider could not be loaded or initialized. when the SYSTEMROOT variable is not set. This can e. g. be achieved by running an exec.Command with a non-nil Env that doesn’t contain the parent process’s environment.
I have written a sample application demonstrating the issue under https://github.com/Xjs/envless-listen.
This issue can be reproduced with go version go1.9 windows/amd64 under Windows 10.
According to https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx, this error occurs if some DLL cannot be loaded, so I assume a Windows socket syscall needs to load a DLL which is not found if SYSTEMROOT is unset.
I don’t know how this issue is best mitigated. I don’t even know if the leverage point is net or rather os/exec. One could imagine something like exec.Cmd never omitting SYSTEMROOT from the environment on Windows, even when passing a non-nil Env. However, if it is possible to infer the system root from some other source, the net package might also consider re-setting it. It might also be fine just leaving it as-is and documenting somewhere that sockets under Windows require access to that library.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 18 (17 by maintainers)
I found some MS reference about sub-process creation, cf. under section
lpEnvironment, https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessaIt appears that Go implements correctly the expected behavior because if
cmd.Envis left tonil, the environment variables are inherited from the parent process. Assigning an empty array as in the example, imposes explicitly to start the sub-process with an empty set of environment variables.The relevant part becomes:
Bugs like this one are why I filed #25210