brettwooldridge / NuProcess

Low-overhead, non-blocking I/O, external Process implementation for Java
Apache License 2.0
712 stars 84 forks source link

`System.getenv()` variables are always passed to a process on Windows #60

Closed ilya-klyuchnikov closed 8 years ago

ilya-klyuchnikov commented 8 years ago

System.getenv() variables (not overwritten ones) are always passed to a process on Windows. The root cause is this line: https://github.com/brettwooldridge/NuProcess/blob/master/src/main/java/com/zaxxer/nuprocess/windows/WindowsProcess.java#L644

MTyson commented 8 years ago

@ilya-klyuchnikov Can you elaborate? That sounds like expected behavior (same as java Process). Or am I misunderstanding?

ilya-klyuchnikov commented 8 years ago

@MTyson, my story is that one test in Buck (https://github.com/brettwooldridge/NuProcess/blob/master/src/main/java/com/zaxxer/nuprocess/windows/WindowsProcess.java#L644) fails on Windows. The root cause is that even if com.zaxxer.nuprocess.NuProcessBuilder#environment.clear() is invoked, a process on Windows will start with a copy of System.getenv() just because it is done in WindowsProcess. As for java Process - you can modify and clear environment:

scala> val pb = new ProcessBuilder("env")
pb: ProcessBuilder = java.lang.ProcessBuilder@62b6c045

scala> pb.environment.clear()

scala> val process = pb.start()
process: Process = java.lang.UNIXProcess@76216830

scala> process.waitFor
res9: Int = 0

scala> scala.io.Source.fromInputStream(process.getInputStream).getLines().mkString("\n")
res10: String = ""

scala>

and windows version:

scala> val pb = new ProcessBuilder("cmd", "/c", "set")
pb: ProcessBuilder = java.lang.ProcessBuilder@7c8c9a05

scala> pb.environment.clear

scala> val process = pb.start
process: Process = java.lang.ProcessImpl@537c8c7e

scala> process.waitFor
res1: Int = 0

scala> scala.io.Source.fromInputStream(process.get
getClass   getErrorStream   getInputStream   getOutputStream

scala> scala.io.Source.fromInputStream(process.getInputStream).getLines.mkString("\n")
res2: String =
COMSPEC=C:\Windows\SYSTEM32\cmd.exe
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS;.MSC
PROMPT=$P$G
SystemRoot=C:\Windows

(COMSPEC, PATHEXT, PROMPT, SystemRoot cannot be eliminated AFIU).

So, on Linux and Mac NuProcessBuilder.environment.clear() has the same behaviour as java.lang.ProcessBuilder.environment.clear(). But on Windows the behavior is different (just because of details of the implementation of WindowsProcess mentioned above).

brettwooldridge commented 8 years ago

Pull requests are welcome. :smile:

ilya-klyuchnikov commented 8 years ago

The pull request is already here for a few days. Could you take a look?