So, this seems trivial, but according to #77, the previous behavior caused a problem with more complicated commands. Granted, it seems weird to call commands like `if [thing]; then true; else false; fi` but here we are. If I add the semicolon, then the shell treats it as a separate command. This means it modifies the shell env, but this is fine in the subshell environment we're running the command in. Normally, if you were running this on your command line, I wouldn't recommend it: as I said, this would modify your environment instead of modifying the command's environment. But we should be good here.
The ProcessRunner and PosixRunner are perfectly capable of taking an environment hash. This means there's no reason to use ClimateControl to modify the environment beforehand. In order to find custom binaries, we can modify the PATH on the command line -- yes, for both Unix and Windows. Unix commandlines use the normal `PATH=/new/path:$PATH cmd` syntax. Windows uses `SET PATH=C:\new\path;%PATH% & cmd` instead. The difference between then and now is that I found out that you can actually separate commands in Windows with `&` (see http://support.microsoft.com/kb/279253). As a result of this the `supplemental_environment` isn't modified when the `path` is modified. We keep the path in memory as a `Cocaine::OS.path_separator`-separated string. In addition, this commit cleans up the OS detection slightly, moving it to a new class. In the future, we can do things like telling instead of asking. The result of all this is that the `ProcessRunner` and `PosixRunner` should be thread-safe, since we're not mucking around with the `ENV` when we run stuff anymore. This will make the high-throughput users of Paperclip happy, since they shouldn't see clobbering issues like they did before. I tested this by running the code supplied by @maxim, thoughtbot/paperclip#1709 (comment), with the unmodified cocaine 0.5.4 gem and with this commit in place. It failed in a few seconds before and ran for as long as I wanted after. This also might fix a bug? Previously, on Java on Windows, commands would be called prefixed with `env`, which doesn't exist on Windows. No one complained, though, so you can guess how popular Java on Windows is (or I'm completely screwing up). Now we look for Windows first, then use `env` with Java, and then Unix like normal.
Even though you can supply an environment to `Process.spawn` and `Posix.spawn`, that doesn't mean they'll use that environment while looking for executables. A modified PATH environment is passed correctly on to the spawned process, but an executable is not searched for in the modified PATH. Given that, we need to modify the environment when `spawn` is called. As `BackticksRunner` and `POpenRunner` both modified the environment already, they worked fine.